3D オブジェクトのインポートおよびテクスチャマッピング ( Android OpenGL フレームワーク “Rajawali” と戯れる #07 )
Android OpenGL フレームワーク "Rajawali" と戯れるシリーズ
第 07 回目は、外部の 3D オブジェクトの取り扱い方について解説します。
Rajawali が提供する 3D オブジェクトパーサ
Rajawali では、下記 3D オブジェクトパーサのクラスが用意されています。
- Max3DSPaser
- ObjParser
- FBXParser
- MD2Paser
- MD5AnimParser
- MD5MeshParser
中にはアニメーションをサポートするクラスもあるのですが、今回はアニメーション情報を保持しない単純な 3D オブジェクトのインポートを目的としているので、ObjParser を題材に解説を進めます。
ObjParser クラスで読み込めるファイルおよびお約束事
Rajawali の ObjParser クラスでは Wavefront OBJ File (*.obj) をパースすることが可能ですが、すべての仕様をカバーしているわけではないようで、最低でも以下のお約束事を守らなければなりません。
- 3D オブジェクトは、三角ポリゴンで構築すること
- テクスチャを使用する場合、UV 座標も書き出すこと
- .obj ファイルのグループを示す "g …" が正しく解釈されないので、"# g …" とコメントアウト or 削除すること
.obj ファイルの詳細仕様については下記を参照してください。
https://en.wikipedia.org/wiki/Wavefront_.obj_file
ObjParser クラスによるパースとデータ取得
実装はとてもシンプルです。
ファイルのパース
ObjParser parser = new ObjParser(mContext.getResources(), mTextureManager, R.raw.≪任意の .obj ファイル≫); paeser.parse();
パースしたデータの取得
BaseObject3D obj = paeser.getParsedObject();
シンプルですね。
取得したデータのテクスチャマッピング
こちらも非常にシンプルです。
Bitmap texture = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.≪任意のテクスチャ画像≫); obj.setMaterial( ≪任意のマテリアルオブジェクト≫ ); obj.addTexture( mTextureManager.addTexture(texture) );
実装例
ソース素材
今更で出尽くした感があるかもしれませんが、三次元CG@七葉にて保管されているズサ氏制作のはちゅねミク 3D オブジェクト+テクスチャ データを拝借してサンプルを作成してみました。( .mpo -> .obj 変換しています )
ちなみに、LightWave 3D で開いた状態は以下のとおり。
ソースコード
Lesson05Renderer.java
package jp.classmethod.sample.renderer; import jp.classmethod.sample.R; import rajawali.BaseObject3D; import rajawali.lights.PointLight; import rajawali.materials.DiffuseMaterial; import rajawali.parser.ObjParser; import rajawali.renderer.RajawaliRenderer; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; /** * RajawaliRenderer のサブクラス */ public class Lesson05Renderer extends RajawaliRenderer { /** パースされた 3D オブジェクトデータ */ private BaseObject3D mObj; /** コンストラクタ */ public Lesson05Renderer(Context context) { super(context); setFrameRate(60); setBackgroundColor(0xffffff); } @Override /** シーン初期化 */ protected void initScene() { Resources r = mContext.getResources(); PointLight light = new PointLight(); light.setPower(1f); light.setColor(0xffffff); light.setPosition(0f, 0f, -2f); Bitmap texture = BitmapFactory.decodeResource(r, R.drawable.miku); ObjParser parser = new ObjParser(r, mTextureManager, R.raw.miku); parser.parse(); mObj = parser.getParsedObject(); mObj.setMaterial(new DiffuseMaterial()); mObj.addTexture( mTextureManager.addTexture(texture) ); mObj.setRotation(25, 190, 0); mObj.setScale(1f); mObj.addLight(light); addChild(mObj); } }
出力結果
DiffuseMaterial で散光させるとホラーホラーしいですね。。。
次回
アニメーション情報付き 3D オブジェクトのインポートについて解説します。